import create from '@/hooks/state-link';
import { ComponentInfo, EditorState } from '@/components/editor';
import { getNextSelectedId } from '@/comon/tools';
import { cloneDeep } from 'lodash';
import { insertComponentInfo } from './tool';
import { nanoid } from 'nanoid';
import { arrayMove } from '@dnd-kit/sortable';

const initState: EditorState = {
  selectedId: '',
  componentList: [],
};

const useStore = create<EditorState>(initState);

export const useEditorStore = () => {
  const [data, setData] = useStore();

  const selectedComponentInfo = data.componentList.find(
    (item) => item.fe_id === data.selectedId
  );

  function reset(value: EditorState) {
    setData(value);
  }

  function select(id: string) {
    data.selectedId = id;
    setData(data);
  }
  // 添加
  function add(newComponent: ComponentInfo) {
    const newData = insertComponentInfo(data, newComponent);
    setData(newData);
  }

  function setList(list: ComponentInfo[]) {
    data.componentList = list;
    setData(data);
  }
  // 更新
  function updateSelected(newInfo: ComponentInfo) {
    const { selectedId, componentList } = data;

    const newList = componentList.map((info) => {
      if (info.fe_id === selectedId) {
        info = {
          ...info,
          ...newInfo,
        };
      }
      return info;
    });

    setList(newList);
  }
  // 删除
  function deleteById() {
    const { componentList, selectedId } = data;

    data.selectedId = getNextSelectedId(selectedId, componentList);
    data.componentList = componentList.filter(
      (info) => info.fe_id !== selectedId
    );

    setData(data);
  }
  // 显示/隐藏
  function showHidden(id: string = '') {
    const { componentList } = data;

    const index = componentList.findIndex((info) => info.fe_id === id);

    // 隐藏->显示
    if (componentList[index]?.isHidden === true) {
      data.selectedId = id;
    }
    // 显示->隐藏
    else {
      data.selectedId = getNextSelectedId(id, componentList);
    }

    data.componentList = data.componentList.map((info) => {
      if (info.fe_id === id) {
        info.isHidden = !info.isHidden;
      }
      return info;
    });

    setData(data);
  }
  // 锁定/解锁
  function toggleLock(id: string = '') {
    const { componentList } = data;
    const index = componentList.findIndex((info) => info.fe_id === id);

    if (index >= 0) {
      componentList[index].isLocked = !componentList[index].isLocked;
    }

    setData(data);
  }

  // 复制
  function copy() {
    if (!selectedComponentInfo) return;
    data.copiedComponentInfo = selectedComponentInfo;
    setData(data);
  }

  // 粘贴
  function paste() {
    const { copiedComponentInfo } = data;
    if (!copiedComponentInfo) {
      return;
    }
    const newComponentInfo = cloneDeep(copiedComponentInfo);
    newComponentInfo.fe_id = nanoid();
    const newData = insertComponentInfo(data, newComponentInfo);
    setData(newData);
  }

  // 向上选择 or 向下选中
  function selectNextOrPrev(arrow: 'next' | 'prev') {
    const { selectedId, componentList } = data;
    let index = componentList.findIndex((info) => info.fe_id === selectedId);

    if (arrow === 'next') index++;
    if (arrow === 'prev') index--;

    const nextInfo = componentList[index];
    if (nextInfo?.fe_id) {
      data.selectedId = nextInfo.fe_id;
      setData(data);
    }
  }

  function dragMove(oldIndex: number, newIndex: number) {
    const { componentList } = data;
    data.componentList = arrayMove(componentList, oldIndex, newIndex);
    setData(data);
  }

  function moveUp(index?: number) {
    if (index === undefined) return;
    const { componentList } = data;
    const oldIndex = index;
    const newIndex = index - 1;
    data.componentList = arrayMove(componentList, oldIndex, newIndex);
    setData(data);
  }

  function moveDown(index?: number) {
    if (index === undefined) return;
    const { componentList } = data;
    const oldIndex = index;
    const newIndex = index + 1;
    data.componentList = arrayMove(componentList, oldIndex, newIndex);
    setData(data);
  }

  return {
    data,
    componentList: data.componentList,
    selectedId: data.selectedId,
    selectedComponentInfo,
    copiedComponentInfo: data.copiedComponentInfo,
    moveDown,
    moveUp,
    dragMove,
    selectNextOrPrev,
    paste,
    copy,
    reset,
    select,
    add,
    deleteById,
    updateSelected,
    showHidden,
    toggleLock,
  };
};
